package com.stenio.fancat.common.interceptor;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSONObject;
import com.stenio.fancat.common.ThreadCache;
import com.stenio.fancat.common.constants.GlobalConstant;
import com.stenio.fancat.common.enums.RequestKey;
import com.stenio.fancat.common.enums.ResultCode;
import com.stenio.fancat.util.JsonUtil;

/**
 * 请求拦截器，统一处理逻辑，如验证身份、请求body内容等
 *
 */
@Component
public class RequestInterceptor implements HandlerInterceptor, InitializingBean {

	private static final Logger logger = LoggerFactory.getLogger(RequestInterceptor.class);

	@Value("${excludeUrls}")
	public String excludeUrls;

	private List<String> urls = new ArrayList<String>();

	/**
	 * 方法调用前执行
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		response.setCharacterEncoding(GlobalConstant.PLATFORM_CHARACTER_ENCODING);
		response.setContentType(GlobalConstant.PLATFORM_RESPONSE_CONTENTTYPE_JSON);
		// 接口放行
		if (urls.contains(request.getRequestURI())) {
			return true;
		}

		String contentType = request.getContentType();
		if (contentType != null) {
			contentType = contentType.toLowerCase();
		}
		String source;
		String version;

		JSONObject requestMap = new JSONObject();
		// 获取请求参数
		String requestJSONStr = ThreadCache.getPostRequestParams();
		logger.info("==> : {}", requestJSONStr);
		if ("POST".equals(request.getMethod().toUpperCase())
				&& (GlobalConstant.PLATFORM_RESPONSE_CONTENTTYPE_JSON.equals(contentType)
						|| GlobalConstant.CONTENTTYPE_JSON_UTF_8.equals(contentType))) {

			// 校验请求信息，是否为json格式
			if (!JsonUtil.isJson(requestJSONStr)) {
				requestMap = new JSONObject();
				requestMap.put(RequestKey.code.name(), ResultCode.PARAM_IS_INVALID.code());
				requestMap.put(RequestKey.msg.name(), ResultCode.PARAM_IS_INVALID.message());
				response.getWriter().write(requestMap.toJSONString());
				logger.warn("json format  invalid : {}", requestJSONStr);
				return false;
			}

			// 字符串格式化为JSONObject
			requestMap = JSONObject.parseObject(requestJSONStr);
			// 校验请求json的必要属性(暂时只校验请求来源)
			source = (String) requestMap.get(RequestKey.source.name());
			version = (String) requestMap.get(RequestKey.version.name());
		} else {
			// 获取请求参数
			source = request.getParameter(RequestKey.source.name());
			version = request.getParameter(RequestKey.version.name());
		}

		if (StringUtils.isBlank(source) && StringUtils.isBlank(version)) {
			requestMap.put(RequestKey.code.name(), ResultCode.PARAM_IS_BLANK.code());
			requestMap.put(RequestKey.msg.name(), ResultCode.PARAM_IS_BLANK.message());
			response.getWriter().write(requestMap.toJSONString());
			logger.warn("require parameter invalid : {}", requestJSONStr);
			return false;
		}

		// 将当前请求的请求参数放入当前请求的线程本地参数中
		return true;
	}

	/**
	 * 方法调用执行
	 */
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {

	}

	/**
	 * 方法调用后执行，清除当前请求线程的本地请求的JSON数据
	 */
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// SystemContext.removeRequestJSON();
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		if (excludeUrls != null) {
			urls.addAll(Arrays.asList(excludeUrls.split(",")));
		}
	}

}